import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:audioplayers/audioplayers.dart';
import 'package:wms/utils/utils.dart';
import '../../services/api_service.dart';
import 'package:provider/provider.dart';
import '../../services/auth_service.dart';
import 'package:flutter/services.dart';
import '../system/fontsize_provider.dart';
import '../../utils/message_box.dart';

class ShipmentOrderItem {
  final String orderId;
  final String internalItemNumber;
  final String itemNumber;
  final int pickedQuantity;
  final String packType;

  ShipmentOrderItem({
    required this.orderId,
    required this.internalItemNumber,
    required this.itemNumber,
    required this.pickedQuantity,
    required this.packType,
  });
}

class ShipmentData {
  final String orderNumber;
  final String trackingNumber;
  final String status;
  final List<ShipmentOrderItem> orderItems;

  ShipmentData({
    required this.orderNumber,
    required this.trackingNumber,
    required this.status,
    required this.orderItems,
  });
}

class ShipmentScreen extends StatefulWidget {
  const ShipmentScreen({super.key});

  @override
  _ShipmentScreenState createState() => _ShipmentScreenState();
}

class _ShipmentScreenState extends State<ShipmentScreen> with WidgetsBindingObserver,TickerProviderStateMixin {
  final _barcodeController = TextEditingController();
  bool _isButtonEnabled = false;
  bool _isLoading = false;
  bool _isReadOnly = false;
  final FocusNode _barcodeFocusNode = FocusNode();
  int? warehouseId;
  bool _isKeyboardVisible = false;
  late double _fontScale;
  ShipmentData? _shipmentData;
  bool _showList = false;
  double baseFontSize = 14;
  double listFontSize = 13;
  int responseCode = 0;
  // 新增：动画相关变量
  late AnimationController _blinkController; // 控制动画时长和循环
  late Animation<double> _blinkAnimation;     // 控制透明度变化
  
  final AudioPlayer _audioPlayer = AudioPlayer();
  bool _audioLoaded = false;

  @override
  void initState() {
    super.initState();
    _isKeyboardVisible = false;
    WidgetsBinding.instance.addObserver(this);
    _barcodeController.addListener(_updateButtonState);
    _barcodeFocusNode.addListener(_handleFocusChange);
    _initAudio();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (mounted) {
        _resetKeyboardState();
      }
    });
     // 2. 初始化动画控制器（闪烁频率：1秒1次，循环反向执行）
    _blinkController = AnimationController(
      vsync: this, // 依赖 TickerProviderStateMixin
      duration: const Duration(milliseconds: 500), // 单次动画时长（越快闪烁越频繁）
    )..repeat(reverse: true); // 循环执行，且反向（1.0→0.0→1.0）

    // 3. 定义透明度动画（从完全显示到完全透明）
    _blinkAnimation = Tween<double>(begin: 1.0, end: 0.3).animate(_blinkController);
  }

  Future<void> _initAudio() async {
    try {
      await _audioPlayer.release(); // 释放旧资源，避免文件冲突
      await _audioPlayer.setSource(AssetSource('sounds/error_beep.mp3'));
      setState(() => _audioLoaded = true);
    } catch (e) {
      print('音频初始化失败: $e');
    }
  }

  Future<void> _playErrorSound() async {
    if (!_audioLoaded) return;
    try {
        await _audioPlayer.play(AssetSource('sounds/error_beep.mp3'));
      // for (int i = 0; i < 3; i++) {
      //   await Future.delayed(const Duration(milliseconds: 500));
      // }
    } catch (e) {
      print('播放提示音失败: $e');
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _barcodeController.dispose();
    _barcodeFocusNode.dispose();
    _audioPlayer.dispose();
    _blinkController.dispose();
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.resumed && mounted) {
      _resetKeyboardState();
    }
  }

  void _resetKeyboardState() {
    setState(() => _isKeyboardVisible = false);
    _barcodeFocusNode.unfocus();
    Future.delayed(const Duration(milliseconds: 50), () {
      if (mounted) {
        _barcodeFocusNode.requestFocus();
        _hideKeyboard();
        Future.delayed(const Duration(milliseconds: 100), () {
          if (mounted) _hideKeyboard();
        });
      }
    });
  }

  void _showKeyboard() async {
    try {
      await SystemChannels.textInput.invokeMethod('TextInput.show');
    } catch (e) {
      print('显示键盘失败: $e');
    }
  }

  void _hideKeyboard() async {
    try {
      await SystemChannels.textInput.invokeMethod('TextInput.hide');
    } catch (e) {
      print('隐藏键盘失败: $e');
    }
  }

  void _handleFocusChange() {
    if (_barcodeFocusNode.hasFocus && !_isKeyboardVisible) {
      _hideKeyboard();
    }
  }

  void _toggleKeyboardVisibility() {
    setState(() => _isKeyboardVisible = !_isKeyboardVisible);
    FocusScope.of(context).requestFocus(_barcodeFocusNode);
    Future.delayed(const Duration(milliseconds: 150), () {
      _isKeyboardVisible ? _showKeyboard() : _hideKeyboard();
    });
  }

  void _updateButtonState() {
    final hasText = _barcodeController.text.trim().isNotEmpty;
    if (_isButtonEnabled != hasText) {
      setState(() => _isButtonEnabled = hasText);
    }
  }

  void _handleScanBarcode(String value) {
    String parsedValue = value;
    try {
      if (value.contains(':')) {
        parsedValue = Utils.parseQRCode(value, 'order number');
      }
    } catch (e) {
      print("JSON解析失败: $e");
      _playErrorSound();
    }
    if (mounted) {
      setState(() {
        _barcodeController.text = parsedValue;
        _barcodeController.selection = TextSelection(
          baseOffset: 0,
          extentOffset: parsedValue.length,
        );
      });
    }
    _handleSubmitted();
  }

  Future<Map<String, dynamic>> _shipmentAPI(String barcode) async {
    final apiUrl = ApiService.baseURL + ApiService.shipment;
    final authService = Provider.of<AuthService>(context, listen: false);
    final accessToken = authService.accessToken;
    
    try {
      final requestBody = {
        "warehouse": warehouseId, 
        "tracking_number": barcode
      };
      final response = await http.post(
        Uri.parse(apiUrl),
        headers: {
          'Authorization': 'JWT $accessToken',
          'x-warehouse-id': '$warehouseId',
          'x-timezone': 'America/Los_Angeles',
          'Content-Type': 'application/json',
          'X-Client-Type':'app'
        },
        body: jsonEncode(requestBody),
      );
      
      if (response.statusCode == 200) {
        String responseBody = utf8.decode(response.bodyBytes);
        Map<String, dynamic> jsonData = json.decode(responseBody);
        if (jsonData['data'] != null) {
          return jsonData;
        } else if (jsonData['code'] == 401) {
          AuthService auth = AuthService();
          auth.logout(context);
          throw 'The session has expired, Please log in again.';
        } else {
          throw jsonData['msg'] ?? 'Unknown error';
        }
      } else {
        throw 'HTTP Error: ${response.statusCode}';
      }
    } catch (e) {
      throw e;
    }
  }
  
  void _handleSubmitted() async {
    if (!_isButtonEnabled || _isLoading) return;
    
    setState(() {
      _isKeyboardVisible = false;
      _isLoading = true;
      _isReadOnly = true;
      _showList = false;
      _shipmentData = null;
      if (_barcodeController.text.isNotEmpty) {
        _barcodeController.selection = TextSelection(
          baseOffset: 0,
          extentOffset: _barcodeController.text.length,
        );
      }
    });
    _hideKeyboard();
    
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => const Center(child: CircularProgressIndicator()),
    );

    try {
      final details = await _shipmentAPI(_barcodeController.text.trim());
      
      if (!mounted) return;
      Navigator.pop(context);
      print('data-----${details['data']}');
      responseCode = details['code'];
      if(responseCode != 2000){
        MessageBox.showMessageBox(context, details['msg'],isError:true);
        _playErrorSound();
      }
      if (details['data'] != null && details['data'].isNotEmpty) {
        final data = details['data'] as Map<String, dynamic>;
        final orderNumber = data['order_number'] as String? ?? '';
        final trackingNumber = data['tracking_number'] as String? ?? '';
        final status = data['status'] as String? ?? '';
        final orderItemsRaw = data['order_items'] as List? ?? [];
        
        final List<ShipmentOrderItem> orderItems = orderItemsRaw.map((itemRaw) {
          if (itemRaw is Map<String, dynamic>) {
            return ShipmentOrderItem(
              orderId: itemRaw['order_id'] as String? ?? '',
              internalItemNumber: itemRaw['internal_item_number'] as String? ?? '',
              itemNumber: itemRaw['item_number'] as String? ?? '',
              pickedQuantity: itemRaw['picked_quantity'] as int? ?? 0,
              packType: itemRaw['pack_type'] as String? ?? '',
            );
          } else {
            return ShipmentOrderItem(
              orderId: '',
              internalItemNumber: '',
              itemNumber: '',
              pickedQuantity: 0,
              packType: '',
            );
          }
        }).toList();
        
        setState(() {
          _shipmentData = ShipmentData(
            orderNumber: orderNumber,
            trackingNumber: trackingNumber,
            status: status,
            orderItems: orderItems,
          );
          _showList = true;
        });
      }
    } catch (e) {
      if (mounted) {
        Navigator.pop(context);
        MessageBox.showMessageBox(context, e.toString(), isError: true);
        setState(() {
          _showList = false;
          _shipmentData = null;
        });
        _playErrorSound();
      }
    } finally {
      if (mounted) {
        setState(() {
          _isLoading = false;
          _isReadOnly = false;
        });
        _resetKeyboardState();
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    _fontScale = Provider.of<FontSizeProvider>(context).fontScale;
    final user = Provider.of<AuthService>(context).currentUser;
    warehouseId = user?.warehouse;
    
    return Scaffold(
      appBar: AppBar(
        title: Text('Shipment', style: TextStyle(fontSize: 18 * _fontScale)),
        automaticallyImplyLeading: false,
        leading: IconButton(
          icon: const Icon(Icons.arrow_back, color: Colors.white),
          onPressed: () => Navigator.pushNamed(context, '/outbound'),
        ),
        actions: [
          IconButton(
            icon: const Icon(Icons.home, color: Colors.white),
            onPressed: () => Navigator.pushNamed(context, '/home'),
          ),
        ],
        backgroundColor: const Color(0xFF008363)
      ),
      body: GestureDetector(
        // 点击空白区域时取消所有输入框焦点
        onTap: () {
          FocusScope.of(context).unfocus();
        },
        // 确保空白区域也能响应点击事件
        behavior: HitTestBehavior.opaque,
        child:Padding(
          padding: const EdgeInsets.all(32),
          child: Column(
            children: [
              const SizedBox(height: 16),
              // 条码输入区域
              Row(
                children: [
                  Expanded(
                    child: TextField(
                      readOnly: _isReadOnly,
                      controller: _barcodeController,
                      focusNode: _barcodeFocusNode,
                      autofocus: false,
                      keyboardType: TextInputType.text,
                      decoration: InputDecoration(
                        labelText: 'Or Enter Barcode Manually',
                        border: const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.zero)),
                        prefixIcon: const Icon(Icons.qr_code),
                        contentPadding: const EdgeInsets.symmetric(vertical: 0, horizontal: 10),
                        suffixIcon: IconButton(
                          icon: Icon(
                            _isKeyboardVisible ? Icons.keyboard_hide : Icons.keyboard,
                            color: const Color(0xFF008363),
                          ),
                          onPressed: _toggleKeyboardVisibility,
                          splashRadius: 24,
                        ),
                        hintText: _isKeyboardVisible 
                            ? 'Type barcode here...' 
                            : 'Ready to scan (tap keyboard icon to type)',
                      ),
                      onChanged: (value) => _updateButtonState(),
                      onSubmitted: (value) => _handleSubmitted(),
                      onTap: () {
                        if (_barcodeController.text.isNotEmpty) {
                          _barcodeController.selection = TextSelection(
                            baseOffset: 0,
                            extentOffset: _barcodeController.text.length,
                          );
                        }
                      },
                    ),
                  ),
                  SizedBox(
                    width: 60,
                    height: 48,
                    child: ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        backgroundColor: _isButtonEnabled ? const Color(0xFF008363) : Colors.grey,
                        shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero),
                        padding: EdgeInsets.all(0)
                      ),
                      onPressed: _isButtonEnabled && !_isLoading ? _handleSubmitted : null,
                      child: _isLoading 
                        ? const CircularProgressIndicator(strokeWidth: 2, color: Colors.white) 
                        : const Text('GO', style: TextStyle(fontSize: 15, color: Colors.white)),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 20),
              // 列表区域：PO和TRACKING值对齐，列表项布局调整
              if (_showList && _shipmentData != null) ...[
                // PO和Tracking信息（固定标签宽度实现值对齐）
                Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 16),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Container(
                        // 条件判断：responseCode != 2000时显示浅红色背景，否则透明
                        color: Colors.transparent,
                        // 保持原有内边距（上下10，左右0），确保与其他行对齐
                        padding: const EdgeInsets.symmetric(vertical: 10),
                        // PO行：标签固定宽度80，确保值对齐
                        child:Row(
                          crossAxisAlignment: CrossAxisAlignment.baseline,
                          textBaseline: TextBaseline.alphabetic,
                          children: [
                            SizedBox(
                              width: 80, // 固定标签宽度
                              child: Text(
                                'Status:',
                                style: TextStyle(
                                  fontWeight: FontWeight.bold,
                                  fontSize: baseFontSize * _fontScale,
                                ),
                              ),
                            ),
                            // 关键修改：用 AnimatedBuilder 控制闪烁（仅红色时生效）
                            if (responseCode != 2000)
                              // 红色状态：显示闪烁文本
                              AnimatedBuilder(
                                animation: _blinkAnimation, // 绑定动画
                                builder: (context, child) {
                                  return Opacity(
                                    opacity: _blinkAnimation.value, // 用动画值控制透明度
                                    child: Text(
                                      _shipmentData!.status,
                                      style: TextStyle(
                                        fontSize: baseFontSize * _fontScale,
                                        fontWeight: FontWeight.bold,
                                        color: Colors.red, // 红色样式不变
                                      ),
                                    ),
                                  );
                                },
                              )
                            else
                              // 正常状态：显示普通文本（无动画）
                              Text(
                                _shipmentData!.status,
                                style: TextStyle(
                                  fontSize: baseFontSize * _fontScale,
                                ),
                              ),
                          ],
                        ),
                      ),
                      const SizedBox(height: 10),
                      // PO行：标签固定宽度80，确保值对齐
                      Row(
                        crossAxisAlignment: CrossAxisAlignment.baseline,
                        textBaseline: TextBaseline.alphabetic,
                        children: [
                          SizedBox(
                            width: 80, // 固定标签宽度
                            child: Text(
                              'SO:',
                              style: TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: baseFontSize * _fontScale,
                              ),
                            ),
                          ),
                          Text(
                            _shipmentData!.orderNumber,
                            style: TextStyle(fontSize: baseFontSize * _fontScale),
                          ),
                        ],
                      ),
                      const SizedBox(height: 10),
                      // TRACKING行：标签固定相同宽度80，与PO值对齐
                      Row(
                        crossAxisAlignment: CrossAxisAlignment.baseline,
                        textBaseline: TextBaseline.alphabetic,
                        children: [
                          SizedBox(
                            width: 80, // 与PO标签宽度一致
                            child: Text(
                              'TRACKING:',
                              style: TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: baseFontSize * _fontScale,
                              ),
                            ),
                          ),
                          Text(
                            _shipmentData!.trackingNumber,
                            style: TextStyle(fontSize: baseFontSize * _fontScale),
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 10),
                // 可滚动列表：商品编号在上，内部编号+数量+包装类型在同一行且均匀分布
                Expanded(
                  child: ListView.builder(
                    physics: const AlwaysScrollableScrollPhysics(),
                    itemCount: _shipmentData!.orderItems.length,
                    itemBuilder: (context, index) {
                      final item = _shipmentData!.orderItems[index];
                      return Container(
                        margin: const EdgeInsets.symmetric(vertical: 2),
                        decoration: BoxDecoration(
                          border: Border.all(color: Colors.grey, width: 1.0),
                          borderRadius: BorderRadius.circular(4.0),
                        ),
                        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            // 商品编号
                            Text(
                              item.itemNumber,
                              style: TextStyle(
                                fontSize: listFontSize * _fontScale,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                            const SizedBox(height: 5),
                            // 内部编号 + 数量 + 包装类型（均匀分布）
                            Row(
                              children: [
                                Expanded(
                                  child: Text(
                                    item.internalItemNumber,
                                    style: TextStyle(
                                      fontSize: listFontSize * _fontScale,
                                    ),
                                  ),
                                ),
                                Expanded(
                                  child: Text(
                                    '${item.pickedQuantity}   ${item.packType}',
                                    textAlign: TextAlign.left,
                                    style: TextStyle(
                                      fontSize: listFontSize * _fontScale,
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          ],
                        ),
                      );
                    },
                  ),
                ),
              ],
            ],
          ),
        ),
      )
    );
  }
}
    